package it.ap.sa.acqua.shared.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.MessageSource;
import org.springframework.util.StopWatch;

import it.ap.sa.core.dao.beans.search.ResponseData;
import it.ap.sa.core.dao.util.TPagingList;
import it.ap.sa.core.pageresolver.web.IPageResolver;
import it.ap.sa.core.utils.JsonParserUtil;
import it.ap.sa.core.utils.ListUtils;
import it.ap.sa.core.utils.LogUtil;
import it.ap.sa.core.utils.costants.ContentTypeEnum;

/**
 * @author Alessandro Paolillo
 */
public abstract class AbstractCtrl implements IPageResolver{
	
	/**
	 * logger
	 */
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	/**
	 * Message bundle di spring mvc
	 */
	private MessageSource messageSource;
	
	/**
	 * Messaggio di successo
	 */
	protected static final String MESSAGE_OPERATION_SUCCESS = "message.operation.success";
	
	/**
	 * Messaggio di errore
	 */
	protected static final String MESSAGE_OPERATION_ERROR = "message.operation.error";
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getPathPages(){
		return "pages/";
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getPathSettingsPages(){
		return "settings/";
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getPathFishPages(){
		return "fis/";
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getPathPlantPages(){
		return "pla/";
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getPathTankPages(){
		return "tan/";
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getMessage(String key, Object[] args, Locale locale){
		return this.messageSource.getMessage(key, args, locale);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getMessage(String key, Locale locale){
		return this.getMessage(key, new Object[]{}, locale);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected String getMessage(String key, HttpServletRequest request){
		return this.getMessage(key, request.getLocale());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByObject(Object object, HttpServletRequest request){
		return this.getResponseDataByObject(object, request.getLocale());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByObject(Object object, Locale locale){
		ResponseData response = new ResponseData(true, object, 1, 1, null);
		response.setMessage(this.getMessage(MESSAGE_OPERATION_SUCCESS, locale));
		return response;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByNull(HttpServletRequest request){
		return this.getResponseDataByNull(request.getLocale());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByNull(Locale locale){
		ResponseData response = new ResponseData(true, "", 0, 0, null);
		response.setMessage(this.getMessage(MESSAGE_OPERATION_SUCCESS, locale));
		return response;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByList(TPagingList<?> list, HttpServletRequest request){
		return this.getResponseDataByList(list, request.getLocale());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByList(TPagingList<?> list, Locale locale){
		ResponseData response = new ResponseData(true
				                                ,list.getData()
				                                ,list.getTotalrecord().intValue()
				                                ,ListUtils.sizeList(list.getData())
				                                ,null
				                                );
		response.setMessage(getMessage(MESSAGE_OPERATION_SUCCESS, locale));
		return response;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByList(List<?> list, Locale locale){
		ResponseData response = new ResponseData(true
				                                ,list
				                                ,list.size()
				                                ,ListUtils.sizeList(list)
				                                ,null
				                                );
		response.setMessage(getMessage(MESSAGE_OPERATION_SUCCESS, locale));
		return response;
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByList(List<?> list, int totalRecords, int totalDisplayRecords, Locale locale){
		ResponseData response = new ResponseData(true
				                                ,list
				                                ,totalRecords
				                                ,totalDisplayRecords
				                                ,null
				                                );
		response.setMessage(getMessage(MESSAGE_OPERATION_SUCCESS, locale));
		return response;
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getResponseDataByHashMap(HashMap<?,?> hashMap, Locale locale){
		ResponseData response = new ResponseData(true
				                                ,hashMap
				                                ,hashMap.size()
				                                ,hashMap.size()
				                                ,null
				                                );
		response.setMessage(getMessage(MESSAGE_OPERATION_SUCCESS, locale));
		return response;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getErrorResponseData(HttpServletRequest request){
		return this.getErrorResponseData(request.getLocale());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected ResponseData getErrorResponseData(Locale locale){
		ResponseData response = new ResponseData();
		response.setSuccess(false);
		response.setMessage(getMessage(MESSAGE_OPERATION_ERROR, locale));
		return response;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected <T> T readJsonInRequest(HttpServletRequest request, Class<T> classe) throws Exception{
		return JsonParserUtil.jsonToObject(request, classe);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	protected void downloadFile(String              pathFile
			                   ,HttpServletResponse response
			                   ,ContentTypeEnum     contentType
	) throws Exception{
		StopWatch stopWatch = LogUtil.startStopWatch("downloadFile");
		logger.info("Start downloadFile");
		FileInputStream fileInputStream = null;
		OutputStream    outputStream    = null;
		try{
			File file = new File(pathFile);
			if(file.exists() == false)
				throw new Exception("File " + pathFile + " non esiste");
			if(file.isDirectory())
				throw new Exception("File " + pathFile + " e' una directory");

			logger.info("Scrittura header");
			response.setContentType(contentType.getContentType());
			response.setHeader     ("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");

			logger.info("Lettura e file e scrittura in response");
			fileInputStream = new FileInputStream(file);
			outputStream    = response.getOutputStream();

			IOUtils.copy(fileInputStream, outputStream);
		}catch(Exception e){
			logger.error("Error in downloadFile", e);
			throw e;
		}finally{
			logger.info(LogUtil.endStopWatch(stopWatch));
			if(fileInputStream != null)
				fileInputStream.close();
			if(outputStream != null){
				outputStream.flush();
				outputStream.close();
			}
		}
	}
	/**
	 * @param messageSource the messageSource to set
	 */
	@Autowired
	@Qualifier("webMessageSource")
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}
}
